#!/usr/bin/env perl

# Generate a .c file showing printf and mpfr_printf output with:
#   * a missing precision field;
#   * a precision field with just a period (".");
#   * a precision field with an explicit precision 0 (".0").

use strict;
use warnings;

my @fct = qw/printf mpfr_printf/;
my @cm  = qw/C M/;
my @lm  = ('', 'R', '', 'M', 'P');
my @v   = qw/d x 0 m p/;
my %n   = (d => 6, e => 18, f => 18);
my $p   = ".0";

# Add tests_start_mpfr / tests_end_mpfr calls when this script is run
# from the MPFR tests directory.
my ($header,$start,$end) = -e "mpfr-test.h" ?
  ('"mpfr-test.h"',
   "\n  tests_start_mpfr ();\n",
   "\n  tests_end_mpfr ();\n") :
  ('<mpfr.h>', '', '');

sub gen_print ($$$)
  {
    my ($m,$l,$f) = @_;
    my $lmf = $lm[$l].$f;
    printf "  %s (\"%-8s: \");\n", $fct[$m], "$cm[$m](%%$lmf)";
    foreach my $i (0..2)
      {
        print "  n = $fct[$m] (\" [%".substr($p,0,$i)."$lmf]\", $v[$l]);\n";
        print "  if (n < 0 || n > $n{$f})  exit (1);\n";
        print "  $fct[$m] (\"%*s\", $n{$f} - n, \"\");\n";
      }
    print "  $fct[$m] (\"\\n\");\n\n";
  }

(my $proc = $0) =~ s:.*/::;

print <<EOF;
/* Generated by $proc */

#include <stdio.h>
#include <stdlib.h>

#include $header

static void tst (double d)
{
  mpfr_t x;
  int n;

  mpfr_init2 (x, 24);
  mpfr_set_d (x, d, MPFR_RNDN);

EOF

  foreach my $i (qw/e f/)
    {
      print "  puts (\"\");\n\n";
      gen_print 0, 0, $i;
      gen_print 1, 0, $i;
      gen_print 1, 1, $i;
    }

print <<EOF;
  mpfr_clear (x);
}

int main (void)
{
  const char *patches = mpfr_get_patches ();
  mp_limb_t m = 0;
  mpfr_prec_t p = 0;
  int n;
$start
EOF

print <<'EOF';
  printf ("GMP .....  Library: %-12s  Header: %d.%d.%d\n",
          gmp_version, __GNU_MP_VERSION, __GNU_MP_VERSION_MINOR,
          __GNU_MP_VERSION_PATCHLEVEL);
  printf ("MPFR ....  Library: %-12s  Header: %s (based on %d.%d.%d)\n",
          mpfr_get_version (), MPFR_VERSION_STRING, MPFR_VERSION_MAJOR,
          MPFR_VERSION_MINOR, MPFR_VERSION_PATCHLEVEL);
  printf ("MPFR patches: %s\n\n", patches[0] ? patches : "[none]");

EOF

  gen_print 0, 2, 'd';
  gen_print 1, 2, 'd';
  gen_print 1, 3, 'd';
  gen_print 1, 4, 'd';

print <<EOF;
  tst (1.2345678);
  tst (0.0);
$end
  return 0;
}
EOF
